<?php

/**
 * Výchozí presenter pro presentry administrátorské části webu.
 *
 * @author David Dusek
 */

use Nette\Security\User;
use CMS\Core;

abstract class AdminPresenter extends BasePresenter
{
    protected $globalConfig = FALSE;
    public $dictionary;    
    
    protected function startup() {
        parent::startup();
        $this->initGlobalConfig();
        $this->initUserPanel();
        $this->initDictionary(); 
        
        if ($this->getPresenter()->getName() != "User:Login") {
            $user = $this->user;
            if (!$user->loggedIn) {
                $this->flashMessage($this->dictionary->translate("user_noRightsErr"), "error");
                $this->redirect(":User:Login:", array('backlink' => $this->storeRequest()));
            }
            
            // nastaveni layoutu pro administrativni cast
            $this->setLayout("_" . $this->globalConfig["adminLayout"]);
            $this->template->menu = $this->core->getAdminMenu($this->user->id);

            $moduleName = preg_replace("#:?[a-zA-Z_0-9]+$#", "", $this->getPresenter()->getName());        
            $this->template->submenu = $this->core->getAdminSubmenu($moduleName, $this->user->id);
        }
        
        
        
        $this->template->title = $this->getName() . " - " . $this->getAction();
        $this->template->stylesheet = $this->globalConfig["stylesheet"];
    }
    
    /**
     * Overeni pristupu ke zdroji pro prihlaseneho uzivatele. Pokud neni zadan
     * parametr resource je pouzit aktualni modul a presenter. Parametr 
     * redirectIfNot nastaveny na TRUE zpusobi ze dojde k presmerovani na login
     * a je vypsano chybove hlaseni o nedostatecnych pravech. Jako role se pouzije
     * uzivatelska skupina prave prihlaseneho uzivatele.
     * @param String $operation
     * @param boolen $redirectIfNot Presmerovat na login kdyz opravneni nema.
     * @param String $resource
     * @return boolean
     */
    protected function isAllowed($operation, $redirectIfNot = FALSE, $resource = FALSE) {
        $res = FALSE;
        $acl = $this->core->runHook("hookUserGetAuthorizator", null, "UserModule");
        if ($acl) {
            $this->getUser()->setAuthorizator($acl);
            
            if ($resource === FALSE) {
                $resource = $this->name;
            }
            
            if ($this->getUser()->isAllowed($resource, $operation)) {
                $res = TRUE;
            }
        } 
        
        if ($redirectIfNot && $res === FALSE) {
            $this->flashMessage($this->dictionary->translate("user_noRightsErr"), "error");
            $this->redirect(":User:Login:");
        }
        
        return $res;
    }
    
    /**
     * Nacteni a ulozeni globalni konfigurace.
     * @throws Nette\Application\ApplicationException 
     */
    public function initGlobalConfig() {
        $configRes = $this->core->runHook("hookGetGlobalConfig", null, "ConfigModule");
                
        if ($configRes !== FALSE) {
            $this->globalConfig = $configRes;
        } else {
            throw new Nette\Application\ApplicationException();
        }
    }
    
    /**
     * Inicializace hodnot pro panel zobrazujici informace o prihlasenem 
     * uzivateli.
     */
    public function initUserPanel() {
        $lang = $this->globalConfig["language"];
        if ($this->user->getIdentity() !== null) {
            $lang = $this->user->getIdentity()->data["lang"];
            
            $userObj = $this->em->find("\CMS\User\Models\User", $this->user->getId());            
            $userPanelInfo = $userObj->degreeBefore . " " . $userObj->name . " " 
                           . $userObj->surname . " " . $userObj->degreeAfter
                           . " (" .  $userObj->group->getName() . ")";
            $this->template->userPanelInfo = $userPanelInfo;
        }
    }
    
    /**
     * Inicializece slovniku pro preklady v presenteru a sablonach. 
     */
    public function initDictionary() {
        $lang = $this->globalConfig["language"];
        if ($this->user->getIdentity() !== null) {
            $lang = $this->user->getIdentity()->data["lang"];
        }
        
        $dictionary = \CMS\Dictionary::getInstance();
        $dictionary->setLangs($lang, $this->globalConfig["language"]);
        $this->dictionary = $dictionary;
    }
    
    /**
     * Pridani makra pro prekald nazvu do nastaveneho jazyka.
     * @param type $template 
     */
    public function templatePrepareFilters($template)
    {
        $latte = new Nette\Latte\Engine;
        $macroSet = new Nette\Latte\Macros\MacroSet($latte->compiler);
        $macroSet->addMacro(
                'dictionary',
                'echo $_presenter->dictionary->translate(%node.word)'
        );
//        $macroSet->addMacro(
//                'nazevmakra', // jmeno makra
//                'echo $dictionary->translate(%node.word)', // cim nahradit oteviraci zavorku
//                'echo "konec"' // cim nahradit zaviraci zavorku (volitelne)
//        );     
        $template->registerFilter($latte);
    }
    
    /**
     * Preklad zadaného indexu hesla do jazyka zvoleneho uyzivatelem. Metoda
     * automaticky doplnuje prefix nazevModulu_.
     * @param String $index index hesla v souboru .lang
     * @return Překlad pro jazyk zvoleny uzivatelem. 
     */
    protected function translate($index) {
        $name = $this->getPresenter()->getName();
        $module = lcfirst(preg_replace("#:?[a-zA-Z_0-9]+$#", "", $name));
        $translate = "";
        
        if (strlen($module) > 0) {
            $translate = $this->dictionary->translate($module . "_" . $index);
        }
        
        return $translate;
    }
    
    /**
     * Vraci titulek pro stranku slozeny z nazvu sekce a podsekce stranky.
     * @param String $section index do slovniku pro nazev sekce
     * @param String $subsection index do slovniku pro nazev podsekce
     * @return String 
     */
    protected function getTitle($section, $subsection) {
        return $this->translate($section) . " - " . $this->translate($subsection);
    }
    
    /**
     * Pridani zaznamu do logu. Metoda zajisti vlozeni prave prihlaseneho
     * uzivatele jako iniciatora akce a prevede pole s informacemi o ulozenych
     * datech do JSON formatu. Nakonec je zavolan hook hookUserAddToLog.
     * @param string $entityName
     * @param int $entityId
     * @param string $link
     * @param string $title Index do prekladoveho slovniku (bez prefixu modulu).
     * @param type $descData Asociativni pole indexDoSlovniku => hodnota. Indexy
     * do slovniku jsou opet bez prefixu oznacujiciho modul.
     */
    protected function addToLog($entityName, $entityId, $link = FALSE, $title = FALSE, $descData = FALSE) {
        if ($this->user->loggedIn) {
            $user = $this->em->find("\CMS\User\Models\User", $this->user->id);
            $data = array();
            $data["user"] = $user;
            $data["entity"] = $entityName;
            $data["entityId"] = $entityId;
            
            if ($link) { $data["link"] = $link; }
            if ($title) { $data["title"] = $this->addModulePrefix($title); }
            if (is_array($descData)) { 
                $desc = array();
                foreach ($descData as $index => $value) {
                    $desc[$this->addModulePrefix($index)] = $value;
                }
                $data["description"] = json_encode($desc); 
            }
            
            $this->core->runHook("hookUserAddToLog", array($data), "UserModule");
        }
    }
    
    /**
     * Pridani prefixu s nazvem modulu pred index do slovniku pro preklad.
     * @param string $string Index do prekladoveho slovniku bez prefixu modulu.
     * @return string Index do prekladoveho slovniku s prefixem aktualniho
     * modulu. 
     */
    protected function addModulePrefix($string) {
        $name = $this->getPresenter()->getName();
        $module = lcfirst(preg_replace("#:?[a-zA-Z_0-9]+$#", "", $name));
        
        return $module . '_' . $string;
    }
}
